package com.schoolvisitors.controller.user;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.schoolvisitors.common.PageResult;
import com.schoolvisitors.context.UserContext;
import com.schoolvisitors.dto.GetCubicleTimeSlotDto;
import com.schoolvisitors.dto.ReservationCubicleDto;
import com.schoolvisitors.entity.Reservation;
import com.schoolvisitors.entity.User;
import com.schoolvisitors.enums.ReservationTypeEnum;
import com.schoolvisitors.exception.BusinessException;
import com.schoolvisitors.response.ResultBody;
import com.schoolvisitors.response.ResultCode;
import com.schoolvisitors.service.CubicleService;
import com.schoolvisitors.vo.ReservationVo;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 隔间控制层
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/user")
public class CubicleController {

    private final CubicleService cubicleService;

    public CubicleController(CubicleService cubicleService) {
        this.cubicleService = cubicleService;
    }

    @PostMapping("/reservationCubicle")
    public ResultBody reservationCubicle(@RequestBody @Valid ReservationCubicleDto reservationCubicleDto) {
        User user = UserContext.getUser();
        cubicleService.reservationCubicle(user.getId(), reservationCubicleDto);
        return ResultBody.success();
    }

    @GetMapping("/getReservations")
    public ResultBody getReservations(
            @RequestParam(value = "type") ReservationTypeEnum type,
            @RequestParam("page") int page,
            @RequestParam("size") int size) {
        User user = UserContext.getUser();
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Order.desc("id")));
        Page<Reservation> reservations = cubicleService.getReservationsVoByUserId(type, user, pageable);
        Page<ReservationVo> voPages = reservations.map(ReservationVo::toVo);

        return ResultBody.success(PageResult.bind(voPages));
    }

    @PostMapping("/getCubicleTimeSlots")
    public ResultBody getCubicleTimeSlots(@RequestBody @Valid GetCubicleTimeSlotDto dto) {
        User user = UserContext.getUser();
        JSONArray data = cubicleService.getTimeSlotsVo(user.getId(), dto.getRoomId(), dto.getCubicleNumber(), dto.getDate());

        return ResultBody.success(data);
    }

    @PostMapping("/cancelCubicleReservation")
    public ResultBody cancelCubicleReservation(@RequestBody JSONObject json) {
        User user = UserContext.getUser();
        Long reservationId = json.getLong("reservationId");
        if (reservationId == null) {
            throw new BusinessException(ResultCode.RESERVATION_NOT_FOUND);
        }
        cubicleService.cancelCubicleReservation(user.getId(), reservationId);
        return ResultBody.success();
    }

}
